﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Apache.Cassandra;

namespace Sandy.Queries
{
    public class GetSliceQuery
    {
        public static IDictionary<string, string> Perform(SandyClient client, SandyFamily family, string key, Range columnRange)
        {
            var parent = new ColumnParent
                             {
                                 Column_family = family.Name
                             };
            var pred = new SlicePredicate
                           {
                               Slice_range = columnRange.ToSliceRange(family)
                           };

            var res = client.Client.get_slice(client.Keyspace, key, parent, pred, ConsistencyLevel.ONE);

            // Prepare our format
            return family.CreateColumnDict(res);
        }

        public static IDictionary<string, string> Perform(SandyClient client, SandyFamily family, string key, IEnumerable<string> cols)
        {
            var parent = new ColumnParent
            {
                Column_family = family.Name
            };
            var pred = new SlicePredicate
            {
                Column_names = cols.Select(family.ColumnNameToBytes).ToList()
            };

            var res = client.Client.get_slice(client.Keyspace, key, parent, pred, ConsistencyLevel.ONE);

            // Prepare our format
            return family.CreateColumnDict(res);
        }

        public static IDictionary<string, string> Perform(SandyClient client, SandyFamily family, string key, string superCol, IEnumerable<string> cols)
        {
            var parent = new ColumnParent
            {
                Column_family = family.Name,
                Super_column = family.SuperColumnNameToBytes(superCol)
            };

            var pred = new SlicePredicate
            {
                Column_names = cols.Select(family.ColumnNameToBytes).ToList()
            };

            var res = client.Client.get_slice(client.Keyspace, key, parent, pred, ConsistencyLevel.ONE);

            // Prepare our format
            return family.CreateColumnDict(res);
        }

        public static IDictionary<string, string> Perform(SandyClient client, SandyFamily family, string key, string superCol, Range colRange)
        {
            var parent = new ColumnParent
            {
                Column_family = family.Name,
                Super_column = family.SuperColumnNameToBytes(superCol)
            };

            var pred = new SlicePredicate
            {
                Slice_range = colRange.ToSliceRange(family)
            };

            var res = client.Client.get_slice(client.Keyspace, key, parent, pred, ConsistencyLevel.ONE);

            // Prepare our format
            return family.CreateColumnDict(res);
        }

        public static IDictionary<string, IDictionary<string, string>> PerformSuper(SandyClient client, 
            SandyFamily family, string key, IEnumerable<string> superCols)
        {
            var pred = new SlicePredicate
               {
                   Column_names = superCols.Select(family.SuperColumnNameToBytes).ToList()
               };

            return PerformSuperInternal(client, family, key, pred);
        }

        public static IDictionary<string, IDictionary<string, string>> PerformSuperInternal(SandyClient client, 
            SandyFamily family, string key, SlicePredicate pred)
        {
            var parent = new ColumnParent
            {
                Column_family = family.Name
            };


            var res = client.Client.get_slice(client.Keyspace, key, parent, pred, ConsistencyLevel.ONE);

            // Prepare our format (scn -> (cn -> cv))
            var dict = new OrderPreservingDictionary<string, IDictionary<string, string>>();

            foreach (var scol in res)
            {
                var columnDict = new OrderPreservingDictionary<string, string>();
                foreach (var col in scol.Super_column.Columns)
                {
                    columnDict.Add(family.ColumnNameToString(col.Name), family.GetValueString(col.Value));
                }

                dict.Add(family.SuperColumnNameToString(scol.Super_column.Name), columnDict);
            }

            return dict;
        }

        public static IDictionary<string, IDictionary<string, string>> PerformSuper(SandyClient client, 
            SandyFamily family, string key, Range superColRange)
        {
            var pred = new SlicePredicate
            {
                Slice_range = superColRange.ToSuperSliceRange(family)
            };

            return PerformSuperInternal(client, family, key, pred);
        }
    }
}